package com.work.shart.gatewary.config.filter;

import cn.hutool.core.util.StrUtil;
import com.work.shart.common.exception.ExceptionEnum;
import com.work.shart.common.result.ResultVo;
import com.work.shart.common.token.JwtTokenUtil;
import lombok.Data;
import net.sf.json.JSONObject;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * 网关全局过滤器
 * 用于拦截请求，确认token是否。是否放行
 *
 * @author cong
 */
@Component
@ConfigurationProperties("token.filter")
@Data
public class AuthFilter implements GlobalFilter, Ordered {
    // 过滤掉不需要授权的服务
    private String[] filterServer;
    // filterServer里部分需要授权的路径
    private String[] filterPath;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 过滤掉不需要授权的服务 TODO
        if (
                StrUtil.containsAny(exchange.getRequest().getPath().pathWithinApplication().elements().get(1).value(), filterServer)
                        && !StrUtil.containsAny(exchange.getRequest().getPath().pathWithinApplication().toString(), filterPath)
        ) {

            return chain.filter(exchange);
        } else {
            // 从http请求头中取出token
            final String token = exchange.getRequest().getHeaders().getFirst(JwtTokenUtil.AUTH_HEADER_KEY);
            if (StrUtil.isEmpty(token)) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.OK);
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                ResultVo resultVo = ResultVo.builder()
                        .code(ExceptionEnum.TOKEN_PLEASE_SEND.getCode())
                        .msg(ExceptionEnum.TOKEN_PLEASE_SEND.getMsg()).build();
                byte[] responseByte = JSONObject.fromObject(resultVo).toString().getBytes(StandardCharsets.UTF_8);
                DataBuffer buffer = response.bufferFactory().wrap(responseByte);
                return response.writeWith(Flux.just(buffer));
            }

            //验证，并获取token内部信息
            ResultVo resultVo = JwtTokenUtil.verifyToken(token);
            if (resultVo.getCode() != 200) {
                ServerHttpResponse response = exchange.getResponse();
                response.setStatusCode(HttpStatus.OK);
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                byte[] responseByte = JSONObject.fromObject(resultVo).toString().getBytes(StandardCharsets.UTF_8);
                DataBuffer buffer = response.bufferFactory().wrap(responseByte);
                return response.writeWith(Flux.just(buffer));
            } else {
                return chain.filter(exchange);
            }
        }

    }

    @Override
    public int getOrder() {
        return -100;
    }


}
